/*
 * pur @ 多线程服务器模板文件
 * date @ 2014.08.14
 * author @ wanghaibin
 */

#include <list>
#include <set>
#include <stdio.h> //sprintf
#include <stdlib.h>
#include <string.h> //memset
#include <sys/epoll.h>
#include <unistd.h> //close
#include <vector>

#include <netdb.h>
#include <sys/socket.h>

#include "sockserver.h"
#include "threadpoolmanager.h"
#include <iostream>
using namespace std;

#define MAX_EVENTS 100000
std::set<int> listenFds;   //当前被监听的句柄序列
std::list<int> connectFds; //已连接待处理句柄

void InsertPorts(std::vector<int> &ports)
{
    for (int i = 0; i < 3; ++i) {
        ports.push_back(15555 + i * 1111);
    }
}
/*
 * pur @ 处理一次连接
 * para @ connfd 已经准备好的句柄
 * para @
 * return @ 0处理完毕，
 *			-1 异常或客户端关闭连接，需要关闭句柄
 */
int handle(int connfd)
{
    cout << "0000" << endl;
    sleep(10);
    return -1;
}

struct ThreadData {
    int m_epollfd; //存放epoll的句柄
    int m_connfd;  //存放已连接句柄
};

/*
 * pur @ 线程处理函数
 * para @ data 传递的ThreadData对象
 * return @
 */
void ThreadFunction(void *data)
{
    ThreadData *td = (ThreadData *)data;
    if (handle(td->m_connfd) < 0) {
        struct epoll_event ev;
        epoll_ctl(td->m_epollfd, EPOLL_CTL_DEL, td->m_connfd, &ev);
        close(td->m_connfd);
    }
    if (NULL != td) {
        cout << "11111" << endl;
        delete td;
        td = NULL;
    }
}

int main(int argc, const char *argv[])
{
    std::vector<int> ports;
    int epollfd = -1;
    struct epoll_event ev, events[MAX_EVENTS];
    InsertPorts(ports);
    ThreadPoolManager manager;
    manager.Init(3000, 250,
                 5); // taskpool is 3000, threadmax is 250, thread init number is 5
    epollfd = epoll_create(MAX_EVENTS);
    if (epollfd == -1) {
        exit(-1);
    }
    ServerSock tmpServer;
    for (size_t i = 0; i < ports.size(); ++i) {
        int fd = tmpServer.CreateServer(ports[i]);
        if (fd > 0) {
            listenFds.insert(fd);
            ev.events = EPOLLIN;
            ev.data.fd = fd;
            if (epoll_ctl(epollfd, EPOLL_CTL_ADD, fd, &ev) == -1) //加入监听队列
            {
                exit(-1);
            }
        }
    }

    for (;;) {
        int nfds = epoll_wait(epollfd, events, MAX_EVENTS, -1);
        if (nfds == -1) {
            exit(-1);
        }
        for (int i = 0; i < nfds; ++i) {
            if (listenFds.find(events[i].data.fd) != listenFds.end()) {
                struct sockaddr clientAddr;
                socklen_t addrLen = sizeof(sockaddr);
                int connfd = -1;
                if ((connfd = accept(events[i].data.fd, &clientAddr, &addrLen)) > 0) {
                    cout << "aaaaa-" << connfd << endl;
                    ev.events = EPOLLET;
                    ev.data.fd = connfd;
                    if (-1 == epoll_ctl(epollfd, EPOLL_CTL_ADD, connfd, &ev)) { //将连接句柄加入到监听队列中
                        cout << "xxxxx-" << connfd << endl;
                        close(connfd);
                    }
                } else {
                    exit(-1);
                }
            } else { //其他业务句柄
                cout << "bbbb---" << events[i].data.fd << endl;
                ThreadData *data = new ThreadData;
                data->m_epollfd = epollfd;
                data->m_connfd = events[i].data.fd;
                if (-1 == manager.Run(ThreadFunction, (void *)data)) { //出错关闭连接
                    epoll_ctl(epollfd, EPOLL_CTL_DEL, events[i].data.fd, &ev);
                    close(events[i].data.fd);
                }
            }
        }
    }
    return 0;
}
